package info.hexin.quartz.redis;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ScanOptions;
import org.springframework.stereotype.Component;

import java.util.Collection;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * Created by Administrator on 2016/1/29.
 */
@Component
public class RedisClientImpl implements RedisClient {
    private Logger logger = LoggerFactory.getLogger(getClass());
    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public Boolean zadd(String key, Double score, Object req) {
        return redisTemplate.opsForZSet().add(key, req, score);
    }

    @Override
    public Boolean hasKey(String key) {
        return redisTemplate.hasKey(key);
    }

    @Override
    public Set<Object> zrange(String key, Long start, Long end) {
        return redisTemplate.opsForZSet().range(key, start, end);
    }

    @Override
    public Long removeRangeByScore(String key, Double min, Double max) {
        return redisTemplate.opsForZSet().removeRangeByScore(key, min, max);
    }

    @Override
    public void set(String key, Object o) {
        redisTemplate.opsForValue().set(key, o);
    }

    @Override
    public void hSet(Object key, Object field, Object value) {
        redisTemplate.opsForHash().put(key, field, value);
    }

    @Override
    public void hRemove(Object key, Object... fields) {
        redisTemplate.opsForHash().delete(key, fields);
    }

    @Override
    public Object hGet(Object key, Object field) {
        return redisTemplate.opsForHash().get(key, field);
    }

    public Object hScan(Object key) {
        return redisTemplate.opsForHash().scan(key, new ScanOptions.ScanOptionsBuilder().build());
    }

    @Override
    public List hvals(Object key) {
        return redisTemplate.opsForHash().values(key);
    }


    @Override
    public Boolean expire(String key, Integer timeout, String timeUnit) {
        TimeUnit unit = TimeUnit.valueOf(timeUnit);
        if (unit == null) {
            logger.error("timeUnit is null return.");
            return false;
        }
        return redisTemplate.expire(key, timeout, unit);
    }

    @Override
    public Double incr(String key) {
        return redisTemplate.opsForValue().increment(key, 1D);
    }

    @Override
    public void delete(String key) {
        redisTemplate.delete(key);
    }

    @Override
    public void delete(Collection keys) {
        redisTemplate.delete(keys);
    }

    @Override
    public Object get(String key) {
        return redisTemplate.opsForValue().get(key);
    }

    @Override
    public void set(String key, Object obj, long time, String timeUnit) {

        TimeUnit unit = TimeUnit.valueOf(timeUnit);
        if (unit == null) {
            logger.error("timeUnit is null return.");
            return;
        }
        redisTemplate.opsForValue().set(key, obj, time, unit);
    }

    @Override
    public Long getSetSize(String key) {
        return redisTemplate.opsForZSet().size(key);
    }

    @Override
    public Long getListSize(String key) {
        return redisTemplate.opsForList().size(key);
    }

    @Override
    public Long getHashSize(String key) {
        return redisTemplate.opsForHash().size(key);
    }

    @Override
    public Set<Object> zPopByScore(String key, Double min, Double max, Long offset, Long count) {
        return redisTemplate.opsForZSet().rangeByScore(key, min, max, offset, count);
    }

    @Override
    public Long listLeftPush(String key, Object val) {
        return redisTemplate.opsForList().leftPush(key, val);
    }

    @Override
    public List listRange(String key, long start, long end) {
        return this.listRange(key, start, end, false);
    }



    @Override
    public List listRange(String key, long start, long end, boolean isLog) {
        // TODO Auto-generated method stub
        List list = redisTemplate.opsForList().range(key, start, end);

        return list;

    }

    @Override
    public Long getExpire(String key, TimeUnit timeUnit) {
        return redisTemplate.getExpire(key, timeUnit);
    }

    @Override
    public boolean setNx(String key, Object value) {
        return redisTemplate.opsForValue().setIfAbsent(key, value);
    }

    @Override
    public Object getSet(String key, Object value) {
        return redisTemplate.opsForValue().getAndSet(key, value);
    }


    @Override
    public boolean setNx(String key, Object value, Integer timeout,
                         String timeUnit) {
        Boolean flag = redisTemplate.opsForValue().setIfAbsent(key, value);
        if (flag) {
            this.expire(key, timeout, timeUnit);
        }
        return flag;
    }

    @Override
    public Integer getUserDaySeq(String userDay) {
        if (redisTemplate.hasKey(userDay)) {
            return incr(userDay).intValue();
        } else {
            Integer va = this.incr(userDay).intValue();
            redisTemplate.expire(userDay, 1, TimeUnit.DAYS);
            return va;
        }
    }

    @Override
    public List mGet(List<String> keys) {
        return redisTemplate.opsForValue().multiGet(keys);
    }
}
